import {
    parseHTML
} from './parser-html';
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g

// 拼出基本格式
function generate(el) {
    // 开始处理模板的基本模型 基本模型拆分理解
    // 1._c的函数包裹 
    // 第一个参数是dom 标签节点，第二个参数是dom 上面的属性，第三个参数如果有子节点
    // 就这接着重复_c的效果
    let children = genChildren(el); // 子节点
    // 拼出基本结构
    let code = `_c("${el.tag}",${
       el.attrs.length?genProps(el.attrs):'undefined'
    }${
        children? `,${children}` :''
    })
    `
    return code;
}

// 拼出属性展示格式
function genProps(attrs) {
    // 处理属性 拼接成属性的字符串
    // style 比较特比在ast中attrs 表现形式 {name: "style", value: "font-size: 14px;color: red"}
    let str = '';
    for (let i = 0; i < attrs.length; i++) {
        let attr = attrs[i];
        if (attr.name === 'style') {
            // 将上面表现形式转换成对象的效果 => {style:{color:'red',font-size:'14px'},id:name,}
            let obj = {};
            attr.value.split(';').forEach(item => {
                let [key, value] = item.split(':');
                obj[key] = value
            });
            attr.value = obj;
        }
        // 这里拼接了逗号
        str += `${attr.name}:${JSON.stringify(attr.value)},`
    }
    // 去除末尾逗号
    return `{${str.slice(0,-1)}}`
}
// 对子节点的处理格式
function genChildren(el) {
    let children = el.children;
    if (children && children.length > 0) {
        return `${children.map(c=>gen(c)).join(',')}`
    } else {
        return false;
    }
}

// 处理子节点中的内容，第一种还是一个dom 第二种是个文本
function gen(node) {

    if (node.type == 1) {
        // 元素标签
        return generate(node);
    } else {
        // 如果是文本
        let text = node.text; //   <div>a {{  name  }} b{{age}} c</div>
        let tokens = [];
        let match, index;
        // 每次的偏移量 buffer.split()
        let lastIndex = defaultTagRE.lastIndex = 0; // 只要是全局匹配 就需要将lastIndex每次匹配的时候调到0处
        while (match = defaultTagRE.exec(text)) {
            index = match.index;
            if (index > lastIndex) {
                tokens.push(JSON.stringify(text.slice(lastIndex, index)));
            }
            tokens.push(`_s(${match[1].trim()})`);
            lastIndex = index + match[0].length;
        }
        if (lastIndex < text.length) {
            tokens.push(JSON.stringify(text.slice(lastIndex)))
        }
        return `_v(${tokens.join('+')})`;
    }
}


export function compileToFunction(template) {
    // 1) 解析html字符串 将html字符串 => ast语法树
    let root = parseHTML(template);
    // 需要将ast语法树生成最终的render函数  就是字符串拼接 （模板引擎）
    let code = generate(root);
    // 核心思路就是将模板转化成 下面这段字符串
    //  <div id="app"><p>hello {{name}}</p> hello</div>
    // 将ast树 再次转化成js的语法
    //  _c("div",{id:app},_c("p",undefined,_v('hello' + _s(name) )),_v('hello'))

    // 所有的模板引擎实现 都需要new Function + with
    let renderFn = new Function(`with(this){ return ${code}}`);


    // vue的render 他返回的是虚拟dom
    return renderFn;
}